/*
 *  Brno University of Technology
 *
 *  Copyright (C) 2009-2010 by Brno University of Technology and the contributors
 *
 *  Complete list of developers available at our web site:
 *
 *       http://spl.utko.feec.vutbr.cz
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/.
 */
package cz.vutbr.feec.utko.ef.evolution;

import java.io.Serializable;

import cz.vutbr.feec.utko.ef.individuals.CrossoverIsNotPossibleException;
import cz.vutbr.feec.utko.ef.individuals.MutationIsNotPossibleException;

/**
 * The Class Chromozome is general template for all the chromozome types. 
 */
public abstract class Chromozome implements Cloneable,
		Serializable, Comparable<Chromozome> {

	private static final long serialVersionUID = -5447851966158015225L;

	/** The cached fitness. */
	private Double cachedFitness;

	/**
	 * Clone deep.
	 * 
	 * @return the chromozome
	 */
	public abstract Chromozome cloneDeep();

	/* (non-Javadoc)
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(Chromozome o) {
		assert o.getCachedFitness() != null;
		assert getCachedFitness() != null;
		return new Double(this.getCachedFitness()).compareTo(o
				.getCachedFitness());
	}

	/**
	 * Crossover.
	 * 
	 * @param ch
	 *            the chromozome
	 * @throws CrossoverIsNotPossibleException
	 *             the crossover is not possible exception
	 */
	public abstract void crossover(Chromozome ch)
			throws CrossoverIsNotPossibleException;

	/**
	 * Gets the cached fitness.
	 * 
	 * @return the cached fitness
	 */
	public Double getCachedFitness() {
		return cachedFitness;
	}

	/**
	 * Gets the result.
	 * 
	 * @return the result
	 */
	public abstract Object getResult();

	/**
	 * Mutate.
	 * 
	 * @throws MutationIsNotPossibleException
	 *             the mutation is not possible exception
	 */
	public abstract void mutate()
			throws MutationIsNotPossibleException;

	/**
	 * Reset cached fitness.
	 */
	public void resetCachedFitness() {
		setCachedFitness(null);
	}
	
	/**
	 * Sets the cached fitness.
	 * 
	 * @param cachedFitness the new cached fitness
	 */
	public void setCachedFitness(Double cachedFitness) {
		this.cachedFitness = cachedFitness;
	}

	/**
	 * Validate.
	 */
	public abstract void validate();

	/**
	 * Visualize.
	 * 
	 * @param filename the filename
	 */
	public void visualize(String filename) {
		visualize(filename, DisplayType.BRIEF);
	}
	
	/**
	 * Visualize.
	 * 
	 * @param filename the filename
	 * @param brief the brief
	 */
	public void visualize(String filename, DisplayType brief) {}
}
